//#include <stdio.h>
#include "my_region_manage.h"


#define FRAMEAGE 3
#define CARNUM_MAX 5

/* xmin, xmax, ymin, ymax */
static RectBox flagRegion_1 = {1070, 1454, 438, 516};   //北1区
static RectBox flagRegion_2 = {1061, 1457, 398, 455};   //北2区
static RectBox flagRegion_3 = {267, 687, 502, 597};   //南1区
static RectBox flagRegion_4 = {267, 703, 554, 641};   //南2区
static RectBox flagRegion_5 = {872, 957, 693, 1080};   //东1区
static RectBox flagRegion_6 = {919, 1004, 683, 1080};   //东2区
static RectBox flagRegion_7 = {795, 887, 0, 339};   //西1区
static RectBox flagRegion_8 = {745, 839, 0, 338};   //西2区


static RectBox region_1 = {1070, 1454, 438, 516};   //北1区
static RectBox region_2 = {1061, 1457, 398, 455};   //北2区
static RectBox region_3 = {267, 687, 502, 597};   //南1区
static RectBox region_4 = {267, 703, 554, 641};   //南2区
static RectBox region_5 = {872, 957, 693, 1080};   //东1区
static RectBox region_6 = {919, 1004, 683, 1080};   //东2区
static RectBox region_7 = {795, 887, 0, 339};   //西1区
static RectBox region_8 = {745, 839, 0, 338};   //西2区
static RectBox region_screen = {0, 1920, 0, 1080};

static int regionSet[FRAMEAGE][REGIONNUM] = {0};
//上面的代码相当于定义了一个3*8的二维数组，即二维数组的长度为，二维数组中的每个元素又是一个长度为8的数组
//访问时 regionSet[i] 代表第i个 regionArr的地址

static int timeSequence[3] = {0,1,2};

static SequencePtr sequencePtr = {0};

static int CheckRegion(RectBox region, RectBox box)
{
    if(box.xmin > region.xmin && box.ymin > region.ymin &&
        region.xmax > box.xmax && region.ymax > box.ymax)
        {
            return 1;
        }
        else{
            return -1;
        }
}

void MyRegionCount(const RectBox *boxes, int objNum, int regionArr[])
{
    for(int i = 0;i < objNum; i++){
        if(CheckRegion(region_1, boxes[i])==1){
            regionArr[0] += 1;
        }
        else if(CheckRegion(region_2, boxes[i])==1){
            regionArr[1] += 1;
        }
        else if(CheckRegion(region_3, boxes[i])==1){
            regionArr[2] += 1;
        }
        else if(CheckRegion(region_4, boxes[i])==1){
            regionArr[3] += 1;
        }
        else if(CheckRegion(region_5, boxes[i])==1){
            regionArr[4] += 1;
        }
        else if(CheckRegion(region_6, boxes[i])==1){
            regionArr[5] += 1;
        }
        else if(CheckRegion(region_7, boxes[i])==1){
            regionArr[6] += 1;
        }
        else if(CheckRegion(region_8, boxes[i])==1){
            regionArr[7] += 1;
        }
        if(CheckRegion(region_screen, boxes[i])==1){
            regionArr[8] += 1;
        }
    }
}

static void Sequence2Abstract(unsigned char regionAbstract[])
{
    for (int i = 0; i < REGIONNUM; i++){
        // 先用牛顿插值预测n(t+1)
        int n_0 = *(sequencePtr.regionPtr_0 + i);
        int n_1 = *(sequencePtr.regionPtr_1 + i);
        int n_2 = *(sequencePtr.regionPtr_2 + i);
        int n_next = 3*n_0 - 3*n_1 + n_2;
        // 计算n(avg)
        float n_avg = (n_next + n_0)/2;
        // 判断拥堵等级
        if(n_avg < CARNUM_MAX/3){
            regionAbstract[i] = 0;
        }else if(n_avg > 2*CARNUM_MAX/3){
            regionAbstract[i] = 2;
        }else{
            regionAbstract[i] = 1;
        }
    }
}

void MyRegionAbstract(const int *regionArr, unsigned char regionAbstract[])
{
    // 先更新指针
    sequencePtr.regionPtr_2 = regionSet[timeSequence[1]];
    sequencePtr.regionPtr_1 = regionSet[timeSequence[0]];
    sequencePtr.regionPtr_0 = regionArr;

    // 计算n均值，得到等级信息，赋值给regionAbstract[]
    Sequence2Abstract(regionAbstract);

    // 存储当前regionArr
    for (int i = 0; i < REGIONNUM; i++){
        regionSet[timeSequence[2]][i] = regionArr[i]; 
    }

    // 更新timeSequence序列
    int timeLastNum = timeSequence[2];
    timeSequence[2] = timeSequence[1];
    timeSequence[1] = timeSequence[0];
    timeSequence[0] = timeLastNum;

}

void MyRegionAbstract2(const int *regionArr, unsigned char regionAbstract[])
{
    for (int i = 0; i < REGIONNUM; i++){
        if(regionArr[i]<=1){
            regionAbstract[i] = 0;
        }
        else if(regionArr[i]>=4){
            regionAbstract[i] = 2;
        }
        else{
            regionAbstract[i] = 1;
        }
    }
}

void MyGetRegion(RectBox regionBoxes[])
{
    regionBoxes[0] = flagRegion_1;
    regionBoxes[1] = flagRegion_2;
    regionBoxes[2] = flagRegion_3;
    regionBoxes[3] = flagRegion_4;
    regionBoxes[4] = flagRegion_5;
    regionBoxes[5] = flagRegion_6;
    regionBoxes[6] = flagRegion_7;
    regionBoxes[7] = flagRegion_8;

}

void MyGetRegion2(const RectBox *anchors, const int *anchorIdx, RectBox regionBoxes[])
{
    int anchorDistence = anchors[anchorIdx[1]].xmin - anchors[anchorIdx[0]].xmax;
    int carLaneWidthHalf = (int)(anchorDistence*3/32);
    // 西方向车道 regionBoxes [6,7] anchor[0]
    regionBoxes[7].ymin = 0;
    regionBoxes[7].ymax = anchors[anchorIdx[0]].ymax + carLaneWidthHalf*2;
    regionBoxes[7].xmin = anchors[anchorIdx[0]].xmax - carLaneWidthHalf;
    regionBoxes[7].xmax = anchors[anchorIdx[0]].xmax + carLaneWidthHalf*3;

    regionBoxes[6].ymin = 0;
    regionBoxes[6].ymax = anchors[anchorIdx[0]].ymax + carLaneWidthHalf*2;
    regionBoxes[6].xmin = anchors[anchorIdx[0]].xmax + carLaneWidthHalf;
    regionBoxes[6].xmax = anchors[anchorIdx[0]].xmax + carLaneWidthHalf*5;

    anchorDistence = anchors[anchorIdx[3]].xmin - anchors[anchorIdx[2]].xmax;
    carLaneWidthHalf = (int)(anchorDistence*3/32);

    // 东方向车道 regionBoxes [4,5] anchor [3]
    regionBoxes[5].ymin = anchors[anchorIdx[3]].ymin - carLaneWidthHalf*2;
    regionBoxes[5].ymax = 1080;
    regionBoxes[5].xmin = anchors[anchorIdx[3]].xmin - carLaneWidthHalf*3;
    regionBoxes[5].xmax = anchors[anchorIdx[3]].xmin + carLaneWidthHalf;

    regionBoxes[4].ymin = anchors[anchorIdx[3]].ymin - carLaneWidthHalf*2;
    regionBoxes[4].ymax = 1080;
    regionBoxes[4].xmin = anchors[anchorIdx[3]].xmin - carLaneWidthHalf*5;
    regionBoxes[4].xmax = anchors[anchorIdx[3]].xmin - carLaneWidthHalf*1;

    anchorDistence = anchors[anchorIdx[2]].ymin - anchors[anchorIdx[0]].ymax;
    carLaneWidthHalf = (int)(anchorDistence*3/32);

    // 南方向车道 regionBoxes [2,3]  anchor[2]
    regionBoxes[3].ymin = anchors[anchorIdx[2]].ymin - carLaneWidthHalf*3;
    regionBoxes[3].ymax = anchors[anchorIdx[2]].ymin + carLaneWidthHalf;
    regionBoxes[3].xmin = 111*2;
    regionBoxes[3].xmax = anchors[anchorIdx[2]].xmax + carLaneWidthHalf*2;

    regionBoxes[2].ymin = anchors[anchorIdx[2]].ymin - carLaneWidthHalf*5;
    regionBoxes[2].ymax = anchors[anchorIdx[2]].ymin - carLaneWidthHalf;
    regionBoxes[2].xmin = 111*2;
    regionBoxes[2].xmax = anchors[anchorIdx[2]].xmax + carLaneWidthHalf*2;

    anchorDistence = anchors[anchorIdx[3]].ymin - anchors[anchorIdx[1]].ymax;
    carLaneWidthHalf = (int)(anchorDistence*3/32);

    // 北方向车道 regionBoxes [0,1]  anchor[1]
    regionBoxes[1].ymin = anchors[anchorIdx[1]].ymax - carLaneWidthHalf;
    regionBoxes[1].ymax = anchors[anchorIdx[1]].ymax + carLaneWidthHalf*3;
    regionBoxes[1].xmin = anchors[anchorIdx[1]].xmin - carLaneWidthHalf*2;
    regionBoxes[1].xmax = 111*2 + 1216;

    regionBoxes[0].ymin = anchors[anchorIdx[1]].ymax + carLaneWidthHalf;
    regionBoxes[0].ymax = anchors[anchorIdx[1]].ymax + carLaneWidthHalf*5;
    regionBoxes[0].xmin = anchors[anchorIdx[1]].xmin - carLaneWidthHalf*2;
    regionBoxes[0].xmax = 111*2 + 1216;

}


void MyRegionCount2(const RectBox *carBoxes, const RectBox *regionBoxes, int carNum, int regionArr[])
{
    for(int i = 0;i < carNum; i++){
        for(int j = 0; j < REGIONNUM; j++){
            if(CheckRegion(regionBoxes[j], carBoxes[i]) == 1){
                regionArr[j] += 1;
                break;
            }
        }
    }
}
